
package com.ljk;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import lombok.Getter;

import java.util.Set;
import java.util.StringJoiner;

/**
 * 验证工具类
 *
 * @author ljk
 * @since 2025/3/20 22:44
 */
public class ValidationUtils {

    // 方案1: 显式管理工厂生命周期
    private static final ValidatorFactory VALIDATOR_FACTORY = Validation.buildDefaultValidatorFactory();
    static {
        VALIDATOR = VALIDATOR_FACTORY.getValidator();
//        VALIDATOR_FACTORY.close();
    }
    @Getter
    private static final Validator VALIDATOR;


    /**
     * 验证对象指定分组的约束
     *
     * @param object 待验证的对象
     * @param groups 验证分组
     * @throws ValidationException 当验证失败时抛出
     */
    public static void validate(Object object, Class<?>... groups) {
        Set<ConstraintViolation<Object>> violations = VALIDATOR.validate(object, groups);
        if (!violations.isEmpty()) {
            String errorMessage = buildErrorMessage(violations);
            throw new ValidationException(errorMessage);
        }
    }

    /**
     * 验证对象的指定属性
     *
     * @param object 待验证的对象
     * @param propertyName 属性名
     * @param groups 验证分组
     * @throws ValidationException 当验证失败时抛出
     */
    public static void validateProperty(Object object, String propertyName, Class<?>... groups) {
        Set<ConstraintViolation<Object>> violations = VALIDATOR.validateProperty(object, propertyName, groups);
        if (!violations.isEmpty()) {
            String errorMessage = buildErrorMessage(violations);
            throw new ValidationException(errorMessage);
        }
    }

    /**
     * 验证指定属性的值
     *
     * @param beanType class类型
     * @param propertyName 属性名
     * @param value 属性值
     * @param groups 验证分组
     * @throws ValidationException 当验证失败时抛出
     */
    public static <T> void validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
        Set<ConstraintViolation<T>> violations = VALIDATOR.validateValue(beanType, propertyName, value, groups);
        if (!violations.isEmpty()) {
            String errorMessage = buildErrorMessage(violations);
            throw new ValidationException(errorMessage);
        }
    }

    /**
     * 构建错误信息
     *
     * @param violations 验证违规集合
     * @return 格式化的错误信息
     */
    private static <T> String buildErrorMessage(Set<ConstraintViolation<T>> violations) {
        StringJoiner sj = new StringJoiner("; ");
        for (ConstraintViolation<T> violation : violations) {
            sj.add(String.format("%s: %s", violation.getPropertyPath(), violation.getMessage()));
        }
        return sj.toString();
    }

    /**
     * 检查对象是否有效而不抛出异常
     *
     * @param object 待验证的对象
     * @return 验证是否通过
     */
    public static boolean isValid(Object object) {
        return VALIDATOR.validate(object).isEmpty();
    }


}
